package controller

import (
	rediscache "ahutoj/web/cache/redis"
	"ahutoj/web/io/constanct"
	"ahutoj/web/io/request"
	"ahutoj/web/io/response"
	"ahutoj/web/logic"
	"ahutoj/web/utils"

	"github.com/gin-gonic/gin"
	"github.com/gin-gonic/gin/binding"
)

// @Summary		登陆
// @Description	用户登录接口 邮箱+密码 UID+密码 邮箱+验证码
// @Tags			Auth
// @Accept			json
// @Produce		json
// @Param			LoginReq	body		request.LoginReq	true	"用户登录信息"
// @Success		200			{object}	response.Permission
// @Router			/api/auth/login/ [post]
func Login(ctx *gin.Context) {
	logger := utils.GetLogInstance()
	req := new(request.LoginReq)
	if err := ctx.ShouldBindWith(req, binding.JSON); err != nil {
		// 请求参数有误，直接返回响应
		logger.Errorf("call ShouldBindWith failed, err = %s", err.Error())
		response.ResponseError(ctx, constanct.InvalidParamCode)
		return
	}
	resp, err := logic.CheckLogin(ctx,req)
	if err != nil {
		// logger.Debugf("call CheckLogin failed,req=%+v,err=%s", utils.Sdump(req), err.Error())
		response.ResponseError(ctx, resp.(constanct.ResCode))
		return
	}
	response.ResponseOK(ctx, resp)
}

// @Summary	注册
// @Description 注册之前首先要绑定邮箱获取凭证 emailregister-email   UID
// @Tags		Auth
// @Accept		json
// @Produce	json
// @Param		User	body		request.User	true	"-"
// @Success	200		{object}	response.RegisterResp
// @Router		/api/auth/register/ [post]
func Register(ctx *gin.Context) {
	logger := utils.GetLogInstance()
	req := new(request.User)
	// 1、 获取参数
	err := ctx.ShouldBindWith(req, binding.JSON)
	if err != nil {
		logger.Errorf("call ShouldBindWith failed, err = %s", err.Error())
		response.ResponseError(ctx, constanct.InvalidParamCode)
		return
	}
	// logger.Infof("req:%+v\n", req)
	var ret string	//获取redis凭证，用完删除
	if ret,err=rediscache.GetEmailRegisterFromRDB(ctx,req.Email);err!=nil{
		logger.Errorf("call GetEmailRegisterFromRDB failed,err=%s",err.Error())
		response.ResponseError(ctx, constanct.ServerErrorCode)
		return 
	}
	if ret!=req.UID{
	    response.ResponseError(ctx, constanct.AUTH_NOT_EMAIL_VERIFY)
		return 
	}
	if err:=rediscache.DelEmailRegisterToRDB(ctx,req.Email);err!=nil{
		logger.Errorf("call DelEmailRegisterToRDB failed,err=%s",err.Error())
		response.ResponseError(ctx, constanct.ServerErrorCode)
		return
	}
	// 2、 处理业务逻辑
	resp, err := logic.DoResiger(ctx, req)
	if err != nil {
		logger.Errorf("call DoResiger failed,req=%+v,err=%s", *req, err.Error())
		response.ResponseError(ctx, constanct.ServerErrorCode)
		return
	}
	// 3、 构建响应值，将处理结果返回
	response.ResponseOK(ctx, resp)
}

// func PasswordForget(ctx *gin.Context) {
// 	logger := utils.GetLogInstance()
// 	req := new(request.PasswordForgetReq)
// 	// 1、 获取参数
// 	err := ctx.ShouldBindWith(req, binding.JSON)
// 	if err != nil {
// 		logger.Errorf("call ShouldBindWith failed, err = %s", err.Error())
// 		response.ResponseError(ctx, constanct.InvalidParamCode)
// 		return
// 	}
// 	logger.Infof("req:%+v\n", req)

// 	resp, err := logic.PassWordForget(ctx, req)
// 	if err != nil {
// 		logger.Errorf("call PassWordForget failed,req=%+v,err=%s", *req, err.Error())
// 		response.ResponseError(ctx, constanct.ServerErrorCode)
// 		return
// 	}
// 	response.ResponseOK(ctx, resp)
// }

// @Summary		退出
// @Description	没什么用，仅仅返回一个200状态码
// @Tags	Auth
// @Accept		json
// @Produce	json
// @Success	200	{object}	response.Response
// @Router		/api/auth/logout/ [post]
func Logout(ctx *gin.Context) {
	response.ResponseOK(ctx, response.CreateResponse(constanct.SuccessCode))
}

// @Summary		验证邮箱
// @Description	包含了Code(1)和URL(0)两种验证方式,发送个验证码到邮箱
// @Tags			Auth
// @Accept			json
// @Produce		json
// @Param			VerifyEmailReq	body		request.VerifyEmailReq	true	"-"
// @Success		200				{object}	response.Response
// @Router			/api/auth/verifyemail/ [post]
func VerifyEmail(ctx *gin.Context) {
	logger := utils.GetLogInstance()
	req := new(request.VerifyEmailReq)
	if err := ctx.ShouldBindWith(req, binding.JSON); err != nil {
		// 请求参数有误，直接返回响应
		logger.Errorf("call ShouldBindWith failed, err = %s", err.Error())
		response.ResponseError(ctx, constanct.InvalidParamCode)
		return
	}
	resp, err := logic.VerifyEmail(ctx, req)
	if err != nil {
		logger.Errorf("call VerifyEmail failed,req=%+v,err=%s", utils.Sdump(req), err.Error())
		response.ResponseError(ctx, resp.(constanct.ResCode))
		return
	}
	response.ResponseOK(ctx, resp)
}
// @Summary	URL邮箱验证
// @Description
// @Tags		Auth
// @Param		token	query		string	true	"-"
// @Param		email	query		string	true	"-"
// @Success	200		{object}	response.Response
// @Router		/api/auth/urlverify [get]
func VerifyEmailURL(ctx *gin.Context) {
	logger := utils.GetLogInstance()
	token := ctx.Query("token")
	email := ctx.Query("email")
	resp, err := logic.VerifyEmailURL(ctx, token, email)
	if err != nil {
		logger.Errorf("call VerifyEmail failed,resp=%+v,err=%s", utils.Sdump(resp), err.Error())
		response.ResponseError(ctx, resp.(constanct.ResCode))
		return
	}
	response.ResponseOK(ctx, resp)
}

// @Summary	Code邮箱验证
// @Description  验证邮箱验证码。Register  0//注册 ForgetPass  1//忘记密码Login  = 2//登录ChangeEmail  = 3//修改邮箱
// @Tags		Auth
// @Accept		json
// @Produce	json
// @Param		CodeVerifyReq	body		request.CodeVerifyReq	true	"-"
// @Success	200				{object}	response.Response
// @Router		/api/auth/codeverify [post]
func VerifyEmailCode(ctx *gin.Context) {
	logger := utils.GetLogInstance()
	req := new(request.CodeVerifyReq)
	if err := ctx.ShouldBindWith(req, binding.JSON); err != nil {
		// 请求参数有误，直接返回响应
		logger.Errorf("call ShouldBindWith failed, err = %s",err.Error())
		response.ResponseError(ctx, constanct.InvalidParamCode)
		return
	}
	resp, err := logic.VerifyEmailCode(ctx, req)
	if err != nil {
		logger.Errorf("call VerifyEmail failed,req=%+v,err=%s", utils.Sdump(req), err.Error())
		response.ResponseError(ctx, resp.(constanct.ResCode))
		return
	}
	response.ResponseOK(ctx, resp)
}

// @Summary	修改邮箱
// @Description  前置api：/api/auth/codeverify
// @Tags		Auth
// @Accept		json
// @Produce	json
// @Param		EmailChangeReq	body		request.EmailChangeReq	true	"-"
// @Success	200				{object}	response.Response
// @Router		/api/auth/emailchange [post]
func EmailChange(ctx *gin.Context) {
	logger := utils.GetLogInstance()
	req := new(request.EmailChangeReq)
	if err := ctx.ShouldBindWith(req, binding.JSON); err != nil {
		// 请求参数有误，直接返回响应
		logger.Errorf("call ShouldBindWith failed, err = %s",err.Error())
		response.ResponseError(ctx, constanct.InvalidParamCode)
		return
	}
	resp, err := logic.EmailChange(ctx, req)
	if err != nil {
		logger.Errorf("call EmailChange failed,req=%+v,err=%s", utils.Sdump(req), err.Error())
		response.ResponseError(ctx, resp.(constanct.ResCode))
		return
	}
	response.ResponseOK(ctx, resp)
}

// @Summary	 QQ授权
// @Description  返回带QQ Code的授权链接
// @Tags		Auth
// @Accept		json
// @Produce	json
// @Success	200				{object}	response.QQAuthResp
// @Router		/api/auth/qqauth [get]
func QQAuth(ctx *gin.Context) {
	logger := utils.GetLogInstance()
	resp, err := logic.QQAuth(ctx)
	if err != nil {
		logger.Errorf("call QQAuth failed,err=%s", err.Error())
		response.ResponseError(ctx, resp.(constanct.ResCode))
		return
	}
	response.ResponseOK(ctx, resp)
}


// @Summary	 QQ获取用户信息
// @Description  通过授权获取对应QQ信息
// @Tags		Auth
// @Accept		json
// @Produce	json
// @Success	200				{object}	response.QQInfoResp
// @Router		/api/auth/qqinfo [get]
func QQInfo(ctx *gin.Context) {
	logger := utils.GetLogInstance()
	req:=new(request.QQInfoReq)
	if err := ctx.ShouldBindWith(req, binding.Query); err != nil {
		// 请求参数有误，直接返回响应
		logger.Errorf("call ShouldBindWith failed, err = %s",err.Error())
		response.ResponseError(ctx, constanct.InvalidParamCode)
		return
	}
	resp, err := logic.QQInfo(ctx,req)
	if err != nil {
		logger.Errorf("call QQInfo failed,err=%s", err.Error())
		response.ResponseError(ctx, constanct.ServerErrorCode)
		return
	}
	response.ResponseOK(ctx, resp)
}
// @Summary	 QQ登录
// @Description  QQ登录，获取QQ用户信息，找到对应UID，自动登陆
// @Tags		Auth
// @Accept		json
// @Produce	json
// @Success	200				{object}	response.QQLoginResp
// @Router		/api/auth/qqlogin [get]
func QQLogin(ctx *gin.Context) {
	logger := utils.GetLogInstance()
	req:=new(request.QQLoginReq)
	if err := ctx.ShouldBindWith(req, binding.Query); err != nil {
		// 请求参数有误，直接返回响应
		logger.Errorf("call ShouldBindWith failed, err = %s",err.Error())
		response.ResponseError(ctx, constanct.InvalidParamCode)
		return
	}
	userinfo,err:=logic.QQInfo(ctx,(*request.QQInfoReq)(req))
	if err!=nil{
		logger.Errorf("call QQInfo failed,err=%s", err.Error())
		response.ResponseError(ctx, constanct.ServerErrorCode)
		return
	}
	resp, err := logic.QQLogin(ctx,userinfo.UserInfo.QQ)
	if err != nil {
		logger.Errorf("call QQLogin failed,err=%s", err.Error())
		response.ResponseError(ctx, resp.(constanct.ResCode))
		return
	}
	response.ResponseOK(ctx, resp)
}

// @Summary	 QQ绑定
// @Description  QQ绑定
// @Tags		Auth
// @Accept		json
// @Produce	json
// @Success	200				{object}	response.QQLoginResp
// @Router		/api/auth/qqbind [get]
func QQBind(ctx *gin.Context) {
	logger := utils.GetLogInstance()
	req:=new(request.QQBindReq)
	if err := ctx.ShouldBindWith(req, binding.Query); err != nil {
		// 请求参数有误，直接返回响应
		logger.Errorf("call ShouldBindWith failed, err = %s",err.Error())
		response.ResponseError(ctx, constanct.InvalidParamCode)
		return
	}
	userinfo,err:=logic.QQInfo(ctx,(*request.QQInfoReq)(req))
	if err!=nil{
		logger.Errorf("call QQInfo failed,err=%s", err.Error())
		response.ResponseError(ctx, constanct.ServerErrorCode)
		return
	}
	resp, err := logic.QQBind(ctx,userinfo.UserInfo.QQ)
	if err != nil {
		logger.Errorf("call QQBind failed,err=%s", err.Error())
		response.ResponseError(ctx, resp.(constanct.ResCode))
		return
	}
	response.ResponseOK(ctx, resp)
}